import DexieCtx from '@/utils/dexiectx';
import GramClient from "@/utils/gramclient";
import Axios from 'axios';
// import user from 'mock/user';
// import { access } from 'original-fs';
import { v4 as uuidv4 } from 'uuid';
const stringUtil = require('@/utils/string')


class GramTgweb {
  /**
   * 
   * @param {*} table 游戏表名/project.name/gameKey
   * @param {*} platform ios|android，默认ios
   */
  constructor(table, platform) {
    this.table = table
    this.platform = platform ?? "ios"
  }

  async allRun() {
    this.dexie = await DexieCtx.db()
    const allAccounts = await this.dexie.accounts.where("session").notEqual("").toArray()
    const project = await this.dexie.projects.get({
      name: this.table,
    })
    let inviteList = project.inviteList || []

    let sepIndex = 0;
    const groupStep = 1
    const sleepNow = (delay) => new Promise((resolve) => setTimeout(resolve, delay))
    while (true) {
      if (sepIndex >= allAccounts.length) {
        break;
      }
      const start = sepIndex
      const end = Math.min(sepIndex + groupStep, allAccounts.length)
      try {
        let promiseList = []
        for (let index = start; index < end; index++) {
          const account = allAccounts[index];
          const gameInfo = await this.dexie[this.table].get({
            phone: account.phone,
          })
          const extGameInfo = gameInfo ?? {}
          if (inviteList.length > 0) {
            const inviteUrl = inviteList[index % inviteList.length]
            extGameInfo.inviteUrl = inviteUrl
          }


          extGameInfo.bot = project.bot
          extGameInfo.channel = project.channel
          extGameInfo.gameUrl = project.gameUrl
          extGameInfo.phone = account.phone

          // if (account.phone == '0051928937201') {
          //   console.log("------------------------------------------>>>")
          // } else {
          //   continue
          // }

          const prms = this.run(account, extGameInfo)
          promiseList.push(prms)
        }
        await Promise.allSettled(promiseList)
        console.log(Date() + "Memefi tgweb finished " + start + "~" + end)
      } catch (error) {
        console.error(error)
      } finally {
        sepIndex = end
      }
    }
  }

  async run(account, extGameInfo) {
    // console.log("extGameInfo   : ", extGameInfo)
    const client = new GramClient(account)

    const sleepNow = (delay) => new Promise((resolve) => setTimeout(resolve, delay))

    try {
      await client.open()
      // /start -> bot
      if (extGameInfo.isJoinBot != true) {
        let startParam = null
        if (this.isBotUrl(extGameInfo.inviteUrl)) {
          startParam = this.getStartParamOfUrl(extGameInfo.inviteUrl)
        }
        const isJoined = await client.startBot(extGameInfo.bot, startParam)
        extGameInfo.isJoinBot = isJoined
        // console.log(this.table, account.phone, "startBot")
      }
      const botGameUrl = await client.getBotStartUrl(extGameInfo.bot)

      let gameUrl = this.isGameUrl(extGameInfo.inviteUrl) ? extGameInfo.inviteUrl : extGameInfo.gameUrl;
      if (gameUrl == null || gameUrl == '') {
        // gameUrl = "https://t.me/memefi_coin_bot/main?startapp=r_9235914f32";
        gameUrl = "https://t.me/memefi_coin_bot/main";

      }
      const bot = extGameInfo.bot;

      let startParam = null
      if (this.isGameUrl(gameUrl)) {
        startParam = this.getStartParamOfUrl(gameUrl)
      }

      console.log("bot        ------")
      console.log(bot)
      console.log("botGameUrl ------")
      console.log(botGameUrl)
      console.log("startParam ------")
      console.log(startParam)

      
      const url = await client.getTgwebUrl(bot, botGameUrl, this.platform, startParam);
      console.log("query_id url", url)
      console.log("=================================>>>>>")
      console.log(url)
      // #tgWebAppData=query_id%3DAAHa4j0yAwAAANriPTIQB4CQ%26user%3D%257B%2522id%2522%253A7285367514%252C%2522first_name%2522%253A%2522elfred%2522%252C%2522last_name%2522%253A%2522Merko%2522%252C%2522username%2522%253A%2522ElfredMerko%2522%252C%2522language_code%2522%253A%2522es%2522%252C%2522allows_write_to_pm%2522%253Atrue%257D%26auth_date%3D1729953709%26hash%3D3bd0877d49028dc7c825ce00067e28192374f5ce92581d669cca8fda59efd2f7&tgWebAppVersion=7.7&tgWebAppPlatform=ios
      // https://tg-app.memefi.club/#tgWebAppData=query_id%3DAAHa4j0yAwAAANriPTJDI5uP%26user%3D%257B%2522id%2522%253A7285367514%252C%2522first_name%2522%253A%2522elfred%2522%252C%2522last_name%2522%253A%2522Merko%2522%252C%2522username%2522%253A%2522ElfredMerko%2522%252C%2522language_code%2522%253A%2522es%2522%252C%2522allows_write_to_pm%2522%253Atrue%257D%26auth_date%3D1729957037%26hash%3D6f0da525c3dfa1fbc00d9905166dc5e1f2ee75b5d40856e41e20adcfac5b2ee5&tgWebAppVersion=7.7&tgWebAppPlatform=ios
      console.log(url.indexOf("query_id"))
      console.log(url.indexOf("%26user"))
      const query_id = url.substring(url.indexOf("query_id") + 11, url.indexOf("%26user"))
      console.log("query_id : ", query_id)

      extGameInfo.tgweb = url
      await this.updateResultTable(client.account, extGameInfo)

      // Codes below are mored from memefi.js, currently these code just could run at Browser
      let webSessionUrl = url

      if (webSessionUrl.startsWith("https://") == false) {
        console.error(`${this.gameInfo.phone}  error session url ${webSessionUrl}`);
        return
      }
      webSessionUrl = decodeURIComponent(webSessionUrl)
      let session = webSessionUrl.split("#tgWebAppData=")[1]
      session = session.split("&tgWebAppVersion")[0]

      const decoded_str = decodeURI(webSessionUrl)

      const user_id = decoded_str.substring(decoded_str.indexOf("\"id\"%3") + 7, decoded_str.indexOf("%2C\"first_name"))
      // console.log("user_id : ", user_id)

      const first_name = decoded_str.substring(decoded_str.indexOf("first_name\"%3A\"") + 15, decoded_str.indexOf("\"%2C\"last_name\""))
      // console.log("first_name : ", first_name)

      let last_name = decoded_str.substring(decoded_str.indexOf("\"%2C\"last_name\"") + 19, decoded_str.indexOf("\"%2C\"language_code\""))

      let username = ''

      if (last_name.indexOf("username") > 0) {
        username = last_name.substring(last_name.indexOf("\"%2C\"username\"%3A\"") + 18)
        last_name = last_name.substring(0, last_name.indexOf("\"%2C\"username"))
      }

      const chat_instance = decoded_str.substring(decoded_str.indexOf("chat_instance=") + 14, decoded_str.indexOf("&chat_type"))
      const start_param = decoded_str.substring(decoded_str.indexOf("start_param=") + 12, decoded_str.indexOf("&auth_date"))
      const auth_date = decoded_str.substring(decoded_str.indexOf("auth_date") + 10, decoded_str.indexOf("&hash"))
      const hash_code = decoded_str.substring(decoded_str.indexOf("hash=") + 5, decoded_str.indexOf("&tgWebAppVersion"))
      const language_code = decoded_str.substring(decoded_str.indexOf("language_code") + 18, decoded_str.indexOf("allows_write_to_pm")-5)

      console.log('11111111111   language_code', language_code)

      let check_str = ""

      // if (username != null && username != '') {
      //   check_str = "auth_date=" + auth_date + "\nchat_instance=" + chat_instance + "\nchat_type=sender\nstart_param=" + start_param + "\nuser={\"id\":" + user_id + ",\"first_name\":\"" + first_name + "\",\"last_name\":\"" + last_name + "\",\"username\":\"" + username + "\",\"language_code\":\"en\",\"allows_write_to_pm\":true}";
      // } else {
      //   check_str = "auth_date=" + auth_date + "\nchat_instance=" + chat_instance + "\nchat_type=sender\nstart_param=" + start_param + "\nuser={\"id\":" + user_id + ",\"first_name\":\"" + first_name + "\",\"last_name\":\"" + last_name + "\",\"language_code\":\"en\",\"allows_write_to_pm\":true}";
      // }


      if (username != null && username != '') {
        check_str = "auth_date=" + auth_date + "\nquery_id=" + query_id + "\nuser={\"id\":" + user_id + ",\"first_name\":\"" + first_name + "\",\"last_name\":\"" + last_name + "\",\"username\":\"" + username + "\",\"language_code\":\""+language_code+"\",\"allows_write_to_pm\":true}";
      } else {
        check_str = "auth_date=" + auth_date + "\nquery_id=" + query_id + "\nuser={\"id\":" + user_id + ",\"first_name\":\"" + first_name + "\",\"last_name\":\"" + last_name + "\",\"language_code\":\""+language_code+"\",\"allows_write_to_pm\":true}";
      }

      // check_str = "auth_date=" + auth_date + "\nquery_id=" + query_id + "\nuser={\"id\":" + user_id + ",\"first_name\":\"" + first_name + "\",\"last_name\":\"" + last_name + "\",\"language_code\":\"en\",\"allows_write_to_pm\":true}";


      let access_token = ''

      const quest_body =
        [
          {
            "operationName": "MutationTelegramUserLogin",
            "variables": {
              "webAppData": {
                "auth_date": parseInt(auth_date),
                "hash": hash_code,
                "query_id": "",
                "checkDataString": check_str,
                "user": {
                  "id": parseInt(user_id),
                  "allows_write_to_pm": true,
                  "first_name": first_name,
                  "last_name": last_name,
                  "username": username,
                  "language_code": "en",
                  "version": "7.7",
                  "platform": "ios"
                }
              },
              "referralCode": start_param
            },
            "query": "mutation MutationTelegramUserLogin($webAppData: TelegramWebAppDataInput!, $referralCode: String) {\n  telegramUserLogin(webAppData: $webAppData, referralCode: $referralCode) {\n    access_token\n    __typename\n  }\n}"
          }
        ]

      const axios = Axios.create({
        timeout: 90 * 1000,
      })

      await sleepNow(1000 * 8)

      await axios.post('https://api-gw-tg.memefi.club/graphql', quest_body, {
        'withCredentials': true,
        'headers': {
          'Content-Type': 'application/json',
        }
      }).then(response => {
        // console.log('response data : ', response.data[0].data.telegramUserLogin.access_token)
        access_token = response.data[0].data.telegramUserLogin.access_token
        console.log("account.phone： ", account.phone)

      }).catch(function (error) {
        console.log("account.phone： ", account.phone)
        console.log(error)
      })

      const authed_req_header = {
        'Content-Type': 'application/json',
        'authorization': 'Bearer ' + access_token
      }

      await sleepNow(1000 * 8)

      let boss_current_health = 0
      let freeBoosts_currentTurboAmount = 0
      let freeBoosts_maxTurboAmount = 0
      let freeBoosts_currentRefillEnergyAmount = 0
      let freeBoosts_maxRefillEnergyAmount = 0

      /* -1. check enemy status  */
      const retrieve_user_info = [
        {
          "operationName": "QUERY_GAME_CONFIG",
          "variables": {},
          "query": "query QUERY_GAME_CONFIG {\n  telegramGameGetConfig {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
        }
      ]

      await axios.post('https://api-gw-tg.memefi.club/graphql', retrieve_user_info, {
        'withCredentials': true,
        'headers': authed_req_header
      }).then(response => {
        // console.log(' --------------------- claim user info ', response)
        // user_balance = response.data[0].data.telegramGameGetConfig.coinsAmount
        boss_current_health = response.data[0].data.telegramGameGetConfig.currentBoss.currentHealth
        freeBoosts_currentTurboAmount = response.data[0].data.telegramGameGetConfig.freeBoosts.currentTurboAmount
        freeBoosts_maxTurboAmount = response.data[0].data.telegramGameGetConfig.freeBoosts.maxTurboAmount
        freeBoosts_currentRefillEnergyAmount = response.data[0].data.telegramGameGetConfig.freeBoosts.currentRefillEnergyAmount
        freeBoosts_maxRefillEnergyAmount = response.data[0].data.telegramGameGetConfig.freeBoosts.maxRefillEnergyAmount


      }).catch(function (error) {
        // console.log( ' ---================--- claim task failed ', error)
        // console.log(error)
      })

      await sleepNow(1000 * 8)

      // currentBoss_level = response.data[0].data.telegramGameGetConfig.currentBoss.level
      if (boss_current_health == 0) {
        // go to next level 
        const next_boss_level = [
          {
            "operationName": "telegramGameSetNextBoss",
            "variables": {},
            "query": "mutation telegramGameSetNextBoss {\n  telegramGameSetNextBoss {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
          }
        ]

        axios.post('https://api-gw-tg.memefi.club/graphql', next_boss_level, {
          'withCredentials': true,
          'headers': authed_req_header
        }).then(response => {
          // console.log('response data : ', response.data)    
        }).catch(function (error) {
          // console.log(error)
        })

        await sleepNow(1000 * 8)
      }

      // 
      // if ( freeBoosts_currentTurboAmount > 0 ) {
      // go to next level 
      const telegramGameActivateBooster = [
        {
          "operationName": "telegramGameActivateBooster",
          "variables": {
            "boosterType": "Recharge"
          },
          "query": "mutation telegramGameActivateBooster($boosterType: BoosterType!) {\n  telegramGameActivateBooster(boosterType: $boosterType) {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
        }
      ]

      axios.post('https://api-gw-tg.memefi.club/graphql', telegramGameActivateBooster, {
        'withCredentials': true,
        'headers': authed_req_header
      }).then(response => {
        // console.log('response data : ', response.data)    
      }).catch(function (error) {
        // console.log(error)
      })
      // }


      const update_random = stringUtil.getRandomIntInclusive(1, 10)

      const EnergyCap = [
        {
          "operationName": "telegramGamePurchaseUpgrade",
          "variables": {
            "upgradeType": "EnergyCap"
          },
          "query": "mutation telegramGamePurchaseUpgrade($upgradeType: UpgradeType!) {\n  telegramGamePurchaseUpgrade(type: $upgradeType) {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
        }
      ]

      if (update_random < 1) {
        axios.post('https://api-gw-tg.memefi.club/graphql', EnergyCap, {
          'withCredentials': true,
          'headers': authed_req_header
        }).then(response => {
          // console.log('response data : ', response.data)    
        }).catch(function (error) {
          // console.log(error)
        })

        await sleepNow(1000 * 8)
        // }
      }

      const EnergyRechargeRate = [
        {
          "operationName": "telegramGamePurchaseUpgrade",
          "variables": {
            "upgradeType": "EnergyRechargeRate"
          },
          "query": "mutation telegramGamePurchaseUpgrade($upgradeType: UpgradeType!) {\n  telegramGamePurchaseUpgrade(type: $upgradeType) {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
        }
      ]

      if (update_random > 10) {
        axios.post('https://api-gw-tg.memefi.club/graphql', EnergyRechargeRate, {
          'withCredentials': true,
          'headers': authed_req_header
        }).then(response => {
          // console.log('response data : ', response.data)    
        }).catch(function (error) {
          // console.log(error)
        })

        await sleepNow(1000 * 8)
        // }
      }


      const telegramGameActivateBoosterDamage = [
        {
          "operationName": "telegramGamePurchaseUpgrade",
          "variables": {
            "upgradeType": "Damage"
          },
          "query": "mutation telegramGamePurchaseUpgrade($upgradeType: UpgradeType!) {\n  telegramGamePurchaseUpgrade(type: $upgradeType) {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
        }
      ]

      if (update_random > 10) {

        axios.post('https://api-gw-tg.memefi.club/graphql', telegramGameActivateBoosterDamage, {
          'withCredentials': true,
          'headers': authed_req_header
        }).then(response => {
          // console.log('response data : ', response.data)    
        }).catch(function (error) {
          // console.log(error)
        })

        await sleepNow(1000 * 8)
        // }
      }

      const telegramGameActivateBoosterTurbo = [
        {
          "operationName": "telegramGameActivateBooster",
          "variables": {
            "boosterType": "Turbo"
          },
          "query": "mutation telegramGameActivateBooster($boosterType: BoosterType!) {\n  telegramGameActivateBooster(boosterType: $boosterType) {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
        }
      ]

      if (update_random > 10) {
        axios.post('https://api-gw-tg.memefi.club/graphql', telegramGameActivateBoosterTurbo, {
          'withCredentials': true,
          'headers': authed_req_header
        }).then(response => {
          // console.log('response data : ', response.data)    
        }).catch(function (error) {
          // console.log(error)
        })

        await sleepNow(1000 * 1)
      }
      // }

      /* 0. hit the enemy  */
      const uuid_1 = uuidv4().replace(new RegExp("-", "gm"), "") + uuidv4().replace(new RegExp("-", "gm"), "")
      const num = stringUtil.getRandomIntInclusive(120, 400)
      let hits = '3';

      for (let index = 0; index < num - 1; index++) {
        hits += ',3'
      }


      // console.log("num ,,,,,,,,,,,,,,,,,,,,,,,   : ", num)
      // console.log("hits,,,,,,,,,,,,,,,,,,,,,,,   : ", hits)

      // random hit counts
      const hit_enemy_campaign_body = [{
        "operationName": "MutationGameProcessTapsBatch",
        "variables": { "payload": { "nonce": uuid_1, "tapsCount": num, "vector": hits } },
        "query": "mutation MutationGameProcessTapsBatch($payload: TelegramGameTapsBatchInput!) {\n  telegramGameProcessTapsBatch(payload: $payload) {\n    ...FragmentBossFightConfig\n    __typename\n  }\n}\n\nfragment FragmentBossFightConfig on TelegramGameConfigOutput {\n  _id\n  coinsAmount\n  currentEnergy\n  maxEnergy\n  weaponLevel\n  zonesCount\n  tapsReward\n  energyLimitLevel\n  energyRechargeLevel\n  tapBotLevel\n  currentBoss {\n    _id\n    level\n    currentHealth\n    maxHealth\n    __typename\n  }\n  freeBoosts {\n    _id\n    currentTurboAmount\n    maxTurboAmount\n    turboLastActivatedAt\n    turboAmountLastRechargeDate\n    currentRefillEnergyAmount\n    maxRefillEnergyAmount\n    refillEnergyLastActivatedAt\n    refillEnergyAmountLastRechargeDate\n    __typename\n  }\n  bonusLeaderDamageEndAt\n  bonusLeaderDamageStartAt\n  bonusLeaderDamageMultiplier\n  nonce\n  spinEnergyNextRechargeAt\n  spinEnergyNonRefillable\n  spinEnergyRefillable\n  spinEnergyTotal\n  spinEnergyStaticLimit\n  __typename\n}"
      }]

      await axios.post('https://api-gw-tg.memefi.club/graphql', hit_enemy_campaign_body, {
        'withCredentials': true,
        'headers': authed_req_header
      }).then(response => {
        console.log('response data : ', response.data)
      }).catch(function (error) {
        console.log(error)
      })

      await sleepNow(1000 * 8)

      /* 1. Get all campaigns  */
      const query_campaign_body = [
        {
          "operationName": "CampaignLists",
          "variables": {},
          "query": "fragment FragmentCampaign on CampaignOutput {\n  id\n  type\n  status\n  backgroundImageUrl\n  campaignUserParticipationId\n  completedTotalTasksAmount\n  description\n  endDate\n  iconUrl\n  isStarted\n  name\n  completionReward {\n    spinEnergyReward\n    coinsReward\n    claimedAt\n    id\n    __typename\n  }\n  totalRewardsPool\n  totalTasksAmount\n  collectedRewardsAmount\n  penaltyAmount\n  penaltySpinEnergyAmount\n  collectedSpinEnergyRewardsAmount\n  totalSpinEnergyRewardsPool\n  __typename\n}\n\nquery CampaignLists {\n  campaignLists {\n    special {\n      ...FragmentCampaign\n      __typename\n    }\n    normal {\n      ...FragmentCampaign\n      __typename\n    }\n    archivedCount\n    __typename\n  }\n}"
        }
      ]

      let campagins = []

      // let special_campaigns = []

      await axios.post('https://api-gw-tg.memefi.club/graphql', query_campaign_body, {
        'withCredentials': true,
        'headers': authed_req_header
      }).then(response => {
        // console.log('response data : ', response.data[0].data.telegramUserLogin.access_token)
        // console.log('campaign : ', response.data[0].data.campaignLists)

        response.data[0].data.campaignLists.special.forEach(function (taskKey, taskValue) {
          campagins.push(taskKey)
        })

        response.data[0].data.campaignLists.normal.forEach(function (taskKey, taskValue) {
          campagins.push(taskKey)
        })
      }).catch(function (error) {
        console.log(error)
      })

      await sleepNow(1000 * 3)

      const tasks = []

      // we just start a random task. 
      const random_value = Math.floor(Math.random() * (campagins.length - 1) + 1)

      const random_task_id = campagins[random_value].id

      // console.log("random_value :", random_value, ", random_task_id :", random_task_id)

      // 根据campaignId获取其下的所有task
      const fetch_tasks_of_campaign = [
        {
          "operationName": "GetTasksList",
          "variables": {
            "campaignId": random_task_id
          },
          "query": "fragment FragmentCampaignTask on CampaignTaskOutput {\n  id\n  name\n  description\n  status\n  type\n  position\n  buttonText\n  coinsRewardAmount\n  spinEnergyRewardAmount\n  link\n  userTaskId\n  isRequired\n  iconUrl\n  taskVerificationType\n  verificationAvailableAt\n  shouldUseVpn\n  isLinkInternal\n  quiz {\n    id\n    question\n    answers\n    __typename\n  }\n  __typename\n}\n\nquery GetTasksList($campaignId: String!) {\n  campaignTasks(campaignConfigId: $campaignId) {\n    ...FragmentCampaignTask\n    __typename\n  }\n}"
        }
      ]

      await axios.post('https://api-gw-tg.memefi.club/graphql', fetch_tasks_of_campaign, {
        'withCredentials': true,
        'headers': authed_req_header
      }).then(response => {
        response.data[0].data.campaignTasks.forEach(function (taskKey, taskValue) {
          // console.log('taskKey  00000000000000000000000000000000000000000000000000000000    ', taskKey)
          tasks.push(taskKey)
        })
      }).catch(function (error) {
        console.log(error)
      })
      // await sleepNow(sleepMillisecond)

      // console.log(tasks)

      await sleepNow(1000 * 3)

      for (let i = 0; i < tasks.length; i++) {

        // console.log('tasks.id    =====+++  ', tasks[i].id)
        // get started of a task

        const tast_status = tasks[i].status
        const userTaskId = tasks[i].userTaskId

        // if tast_status is Pending then we need start task ( CampaignTaskToVerification ), otherwise if is Verification we need complete tast (CampaignTaskMarkAsCompleted) 

        if (tast_status == 'Pending') {
          const get_start_of_tasks = [
            {
              "operationName": "CampaignTaskToVerification",
              "variables": {
                "taskConfigId": tasks[i].id
              },
              "query": "fragment FragmentCampaignTask on CampaignTaskOutput {\n  id\n  name\n  description\n  status\n  type\n  position\n  buttonText\n  coinsRewardAmount\n  spinEnergyRewardAmount\n  link\n  userTaskId\n  isRequired\n  iconUrl\n  taskVerificationType\n  verificationAvailableAt\n  shouldUseVpn\n  isLinkInternal\n  quiz {\n    id\n    question\n    answers\n    __typename\n  }\n  __typename\n}\n\nmutation CampaignTaskToVerification($taskConfigId: String!) {\n  campaignTaskMoveToVerificationV2(taskConfigId: $taskConfigId) {\n    ...FragmentCampaignTask\n    __typename\n  }\n}"
            }
          ]

          // let userTaskId = ''

          await axios.post('https://api-gw-tg.memefi.club/graphql', get_start_of_tasks, {
            'withCredentials': true,
            'headers': authed_req_header
          }).then(response => {
            // userTaskId = response.data[0].data.campaignTaskMoveToVerificationV2.userTaskId
          }).catch(function (error) {
            console.log(error)
          })

        } else if (tast_status == 'Verification') {
          const claim_task = [
            {
              "operationName": "CampaignTaskMarkAsCompleted",
              "variables": {
                "userTaskId": userTaskId
              },
              "query": "fragment FragmentCampaignTask on CampaignTaskOutput {\n  id\n  name\n  description\n  status\n  type\n  position\n  buttonText\n  coinsRewardAmount\n  spinEnergyRewardAmount\n  link\n  userTaskId\n  isRequired\n  iconUrl\n  taskVerificationType\n  verificationAvailableAt\n  shouldUseVpn\n  isLinkInternal\n  quiz {\n    id\n    question\n    answers\n    __typename\n  }\n  __typename\n}\n\nmutation CampaignTaskMarkAsCompleted($userTaskId: String!, $verificationCode: String, $quizAnswers: [CampaignTaskQuizQuestionInput!]) {\n  campaignTaskMarkAsCompleted(\n    userTaskId: $userTaskId\n    verificationCode: $verificationCode\n    quizAnswers: $quizAnswers\n  ) {\n    ...FragmentCampaignTask\n    __typename\n  }\n}"
            }
          ]

          await axios.post('https://api-gw-tg.memefi.club/graphql', claim_task, {
            'withCredentials': true,
            'headers': authed_req_header
          }).then(response => {
            // console.log( ' --------------------- claim task ',response)
          }).catch(function (error) {
            // console.log( ' ---================--- claim task failed ', error)
            // console.log(error)
          })
        }
        await sleepNow(1000 * 10)
      }

      /* 3. get wallet information */
      const retrieve_user_wallet = [
        {
          "operationName": "TelegramMemefiWallet",
          "variables": {},
          "query": "query TelegramMemefiWallet {\n  telegramMemefiWallet {\n    walletAddress\n    dropMemefiAmountWei\n    signedTransaction {\n      contractAddress\n      functionName\n      contractType\n      deadline\n      nativeTokenValue\n      chainId\n      execTransactionValuesStringified\n      __typename\n    }\n    __typename\n  }\n}"
        }
      ]

      let walletAddress = '未绑定'

      await axios.post('https://api-gw-tg.memefi.club/graphql', retrieve_user_wallet, {
        'withCredentials': true,
        'headers': authed_req_header
      }).then(response => {
        console.log(' --------------------- retrieve wallet info   telegramMemefiWallet ', response.data[0].data.telegramMemefiWallet)

        if (response.data[0].data.telegramMemefiWallet != null) {
          walletAddress = response.data[0].data.telegramMemefiWallet.walletAddress
        } else {
          console.log('account wallet is null, neet setup ')
          console.log('account.phone :', account.phone)
          console.log('account.eth_wallet_address   :', account.eth_wallet_address)
          console.log('account.eth_wallet_signature :', account.eth_wallet_signature)

          const setup_wallet = [{ "operationName": "TelegramWalletLink", "variables": { "input": { "signature": account.eth_wallet_signature, "walletAddress": account.eth_wallet_address } }, "query": "mutation TelegramWalletLink($input: TelegramMemefiWalletLinkInput!) {\n  telegramWalletLink(input: $input)\n}" }]

          axios.post('https://api-gw-tg.memefi.club/graphql', setup_wallet, {
            'withCredentials': true,
            'headers': authed_req_header
          }).then(response => {
            // console.log(' --------------------- setup wallet :', response)
            // check the binding status again
            axios.post('https://api-gw-tg.memefi.club/graphql', retrieve_user_wallet, {
              'withCredentials': true,
              'headers': authed_req_header
            }).then(response => {
              console.log(' --------------------- retrieve wallet info   telegramMemefiWallet ', response.data[0].data.telegramMemefiWallet)
              if (response.data[0].data.telegramMemefiWallet != null) {
                walletAddress = response.data[0].data.telegramMemefiWallet.walletAddress
              }
            }).catch(function (error) {
              console.log(' --------------------- retrieve wallet ERROR  ', error)
            })
          }).catch(function (error) {
            console.log(' --------------------- setup wallet ERROR  ', error)
          })
        }
      }).catch(function (error) {
        console.log(' --------------------- retrieve wallet ERROR  ', error)
      })


      /* 4. update user balance */


      let user_balance = ''
      let currentBoss_currentHealth = ''
      let currentBoss_level = ''

      await axios.post('https://api-gw-tg.memefi.club/graphql', retrieve_user_info, {
        'withCredentials': true,
        'headers': authed_req_header
      }).then(response => {
        // console.log(' --------------------- claim user info ', response)
        user_balance = response.data[0].data.telegramGameGetConfig.coinsAmount
        currentBoss_currentHealth = response.data[0].data.telegramGameGetConfig.currentBoss.currentHealth
        currentBoss_level = response.data[0].data.telegramGameGetConfig.currentBoss.level
      }).catch(function (error) {
        // console.log( ' ---================--- claim task failed ', error)
        // console.log(error)
      })

      // console.log('user_balance  ------------------------    ', user_balance)

      if (user_balance > 0) {
        const oldValue = await this.dexie.memefi.get({
          phone: account.phone
        })

        const new_count = (oldValue.count || 0) + 1

        // console.log('new count_________________________     ', new_count)

        await this.dexie.memefi.where('phone').equals(account.phone).modify({
          score: user_balance,
          gameupdate: (new Date()).toLocaleString(),
          count: new_count,
          currentBoss_currentHealth: currentBoss_currentHealth,
          currentBoss_level: currentBoss_level,
          airdrop_wallet: walletAddress
        })
      }
    } catch (error) {
      console.error(account.phone, error)
    } finally {
      await client.close()
    }
  }

  async updateResultTable(account, extGameInfo) {
    if (extGameInfo.tgweb == null) {
      return
    }
    const oldValue = await this.dexie[this.table].get({
      phone: extGameInfo.phone
    })
    const dateStr = (new Date()).toLocaleString()
    extGameInfo.tokenupdate = dateStr
    if (oldValue == null) {
      await this.dexie[this.table].add(extGameInfo)
    } else {
      await this.dexie[this.table].where("phone").equals(extGameInfo.phone).modify(extGameInfo)
    }
  }

  isBotUrl(url) {
    if (url == null) {
      return false
    }
    return url.indexOf("start=") >= 0
  }

  isGameUrl(url) {
    if (url == null) {
      return false
    }
    return url.indexOf("startapp=") >= 0
  }

  getStartParamOfUrl(url) {
    if (url.indexOf("start=") >= 0) {
      return url.split("start=")[1]
    } else if (url.indexOf("startapp=") >= 0) {
      return url.split("startapp=")[1]
    } else {
      return null
    }
  }
}

export default GramTgweb